﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AthCommander.Model;
using AthCommander.Infrastructure;
using System.IO;
using AthCommander.DirectoryGrid.Dialogs;

namespace AthCommander.DirectoryGrid
{
    public partial class Grid : UserControl
    {
        #region History

        private List<FileView> _history;
        private int _currentIndex;

        #endregion

        #region Directory

        private DirectoryView _directory;
        public DirectoryView Directory 
        {
            get
            {
                return _directory;
            }
        }

        #endregion

        private HeaderType _lastSortHeader;
        private DriveCollectionView _drives;
        private DriveView _homeDrive;

        public Grid()
        {
            InitializeComponent();
            _history = new List<FileView>();
            _currentIndex = 0;
            _lastSortHeader = HeaderType.None;
        }

        #region Methods

        public void GoHome()
        {
            _directory.Activate(_homeDrive.Root);
            currentPath.Text = _directory.Directory.FullName;
        }

        public void GoUp()
        {
            _directory.Up();
            _history.Add(_directory.Directory);
            _currentIndex++;
            currentPath.Text = _directory.Directory.FullName;
        }

        public void GoBack()
        {
            if (_currentIndex > 0)
            {
                var file = _history.ElementAt(--_currentIndex);
                _directory.Activate(file);
                currentPath.Text = _directory.Directory.FullName;
            }
        }

        public void GoFoward()
        {
            if (_currentIndex < _history.Count - 1)
            {
                var file = _history.ElementAt(++_currentIndex);
                _directory.Activate(file);
                currentPath.Text = _directory.Directory.FullName;
            }
        }

        #endregion

        #region Private Helpers

        private void Init()
        {
            string path = Environment.GetFolderPath(Environment.SpecialFolder.Windows);
            string info = System.IO.Directory.GetDirectoryRoot(path);

            _directory = new DirectoryView(info);
            this.FileViewBindingSource.DataSource = _directory;

            _drives = new DriveCollectionView();
            this.DriveCollectionViewBindingSource.DataSource = _drives;

            drives.SelectedItem = _homeDrive = _drives.Single(n => n.Root == info);
        }

        private void OpenDirectory(int index)
        {
            this.Cursor = Cursors.WaitCursor;
            if (index >= 0)
            {
                var file = _directory.ElementAt(index);
                _directory.Activate(file);
                _history.Add(file);
                _currentIndex++;
                currentPath.Text = _directory.Directory.FullName;
                _lastSortHeader = HeaderType.None;
            }
            this.Cursor = Cursors.Arrow;
        }

        #endregion

        #region Event Handlers

        private void Grid_Load(object sender, EventArgs e)
        {
            Init();
            DataGridViewColumn col = this.directoryGrid.Columns["Size"];

            if (null != col)
            {
                DataGridViewCellStyle style = col.HeaderCell.Style;

                style.Padding = new Padding(style.Padding.Left, style.Padding.Top, 6, style.Padding.Bottom);
                style.Alignment = DataGridViewContentAlignment.MiddleRight;
            }

            // Select first item
            col = this.directoryGrid.Columns["Name"];

            if (null != col)
            {
                this.directoryGrid.Rows[0].Cells[col.Index].Selected = true;
            }

            _history.Add(_directory.Directory);
            currentPath.Text = _directory.Directory.FullName;
        }

        private void directoryGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if (this.directoryGrid.Columns[e.ColumnIndex].Name == "SizeColumn")
            {
                long size = (long)e.Value;

                if (size < 0)
                {
                    e.Value = "";
                }
                else
                {
                    size = ((size + 999) / 1000);
                    e.Value = size.ToString() + " " + "KB";
                }
            }
        }

        // Otwieranie przodka
        private void directoryGrid_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                this.Cursor = Cursors.WaitCursor;
                OpenDirectory(e.RowIndex);
                this.Cursor = Cursors.Arrow;
            }
            catch (Exception error)
            {
                MessageBox.Show(error.Message);
                this.Cursor = Cursors.Arrow;
            }
        }

        private void directoryGrid_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                var grid = (DataGridView)sender;
                int index = grid.CurrentCell.RowIndex;

                if (_directory.Count > 0)
                {
                    var file = _directory.ElementAt(index);
                    DirectoryInfo root = System.IO.Directory.GetParent(file.FullName);
                    string destinPath = Path.Combine(root.FullName, file.Name);

                    if (string.Compare(destinPath, file.FullName) != 0)
                    {
                        if (file.IsDirectory)
                        {
                            System.IO.Directory.Move(file.FullName, destinPath);
                        }
                        else
                        {
                            File.Move(file.FullName, destinPath);
                        }
                    }
                }
            }
            catch (Exception error)
            {
                MessageBox.Show(error.Message);
            }
        }

        private void directoryGrid_ColumnClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            HeaderType type = (HeaderType)e.ColumnIndex;
            switch (type)
            {
                case HeaderType.Name:
                    if (_lastSortHeader != type)
                    {
                        _directory.SortAscending(n => n.Name);
                        _lastSortHeader = type;
                    }
                    else
                    {
                        _directory.SortDescending(n => n.Name);
                        _lastSortHeader = HeaderType.None;
                    }
                    break;
                case HeaderType.Size:
                    if (_lastSortHeader != type)
                    {
                        _directory.SortAscending(n => n.Size);
                        _lastSortHeader = type;
                    }
                    else
                    {
                        _directory.SortDescending(n => n.Size);
                        _lastSortHeader = HeaderType.None;
                    }
                    break;
                case HeaderType.DateModified:
                    if (_lastSortHeader != type)
                    {
                        _directory.SortAscending(n => n.DateModified);
                        _lastSortHeader = type;
                    }
                    else
                    {
                        _directory.SortDescending(n => n.DateModified);
                        _lastSortHeader = HeaderType.None;
                    }
                    break;
                case HeaderType.Type:
                    if (_lastSortHeader != type)
                    {
                        _directory.SortAscending(n => n.Type);
                        _lastSortHeader = type;
                    }
                    else
                    {
                        _directory.SortDescending(n => n.Type);
                        _lastSortHeader = HeaderType.None;
                    }
                    break;
                default:
                    break;
            }
        }

        private void directoryGrid_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                directoryGrid.ContextMenu.Show(directoryGrid, new Point(e.ColumnIndex, e.RowIndex));
            }
        }

        private void drives_SelectedIndexChanged(object sender, EventArgs e)
        {
            var item = drives.SelectedItem as DriveView;
            try
            {
                this.Cursor = Cursors.WaitCursor;
                if (item != null)
                {
                    _homeDrive = item;
                    _directory.Activate(item.Root);
                    _directory.ResetBindings();
                    _currentIndex = 0;
                    currentPath.Text = _directory.Directory.FullName;
                    _lastSortHeader = HeaderType.None;
                }
                this.Cursor = Cursors.Arrow;
            }
            catch (Exception error)
            {
                MessageBox.Show(error.Message);
                this.Cursor = Cursors.Arrow;
            }
        }

        private void directoryContextMenuOpen_Click(object sender, EventArgs e)
        {
            try
            {
                OpenDirectory(directoryGrid.CurrentRow.Index);
            }
            catch (Exception error)
            {
                MessageBox.Show(error.Message);
            }
        }

        private void directoryContextMenuCopy_Click(object sender, EventArgs e)
        {
            try
            {
                _directory.Watcher.EnableRaisingEvents = false;
                int index = directoryGrid.CurrentRow.Index;
                var file = _directory.ElementAt(index);
                CopyDialog dialog = new CopyDialog(file);
                dialog.ShowDialog();
                dialog.Dispose();
                _directory.Watcher.EnableRaisingEvents = true;
                _directory.Activate(_directory.Directory);
            }
            catch (Exception error)
            {
                MessageBox.Show(error.Message);
            }
        }

        private void directoryContextMenuRename_Click(object sender, EventArgs e)
        {
            try
            {
                _directory.Watcher.EnableRaisingEvents = false;
                int index = directoryGrid.CurrentRow.Index;
                var file = _directory.ElementAt(index);
                RenameDialog dialog = new RenameDialog(file);
                dialog.ShowDialog();
                dialog.Dispose();
                _directory.Watcher.EnableRaisingEvents = false;
                _directory.Activate(_directory.Directory);
            }
            catch (Exception error)
            {
                MessageBox.Show(error.Message);
            }
        }

        private void directoryContextMenuDelete_Click(object sender, EventArgs e)
        {
            try
            {
                _directory.Watcher.EnableRaisingEvents = false;
                int index = directoryGrid.CurrentRow.Index;
                var file = _directory.ElementAt(index);
                DeleteDialog dialog = new DeleteDialog(file);
                dialog.ShowDialog();
                dialog.Dispose();
                _directory.Watcher.EnableRaisingEvents = false;
                _directory.Activate(_directory.Directory);
            }
            catch (Exception error)
            {
                MessageBox.Show(error.Message);
            }
        }

        #endregion


    }
}
